/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ventas.beans;

import datamodel.FiltradoDataModel;
import entities.C;
import entities.LineaPedido;
import entities.Pedido;
import entities.Producto;
import entities.ProductoTalla;
import entities.SerieTallaje;
import entities.Talla;
import entities.TallaSerieTallaje;
import facades.LineaPedidoFacade;
import facades.PedidoFacade;
import facades.ProductoTallaFacade;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.apache.commons.collections.map.MultiKeyMap;
import productos.qualifiers.EventoFiltrarProducto;
import qualifiers.EventoEntidadCreada;
import qualifiers.EventoEntidadEditada;
import qualifiers.EventoEntidadElegida;
import qualifiers.resources.MapaProductosTalla;
import sql.FiltradoProductosSQLGenerator;
import ventas.datamodel.TablaPedidoDataModel;

/**
 *
 * @author damfercer
 */
@Named(value = "editarPedidoBean")
@SessionScoped
public class EditarPedidoBean implements Serializable {
    @Inject
    private PedidoFacade pedidoFacade;
    private FiltradoDataModel filtradoDataModel;
    @Inject
    @EventoFiltrarProducto
    Event<FiltradoDataModel> eventoFiltrarProducto;
    @Inject
    private TablaPedidoDataModel tablaPedidoDataModel;
    private FiltradoProductosSQLGenerator filtradoSQLGenerator;
    private Pedido pedido;
    @Inject
    @EventoEntidadEditada
    private Event<Pedido> eventoPedidoEditado;
    private Map<Integer, LineaPedido> lineasPedido;
    @Inject
    private LineaPedidoFacade lineaPedidoFacade;
    @Inject
    private ProductoTallaFacade productoTallaFacade;
    //TODO: hay que rehacer esto
//    @Inject
//    @EventoEntidadEditada
//    Event<Integer> eventoEditarPedido;
    @Inject
    @MapaProductosTalla
    private MultiKeyMap mapaProductosTalla;
    Map<Integer,Integer> idsEnEspera;
    //Prueba
    /**
     * Creates a new instance of EditarPedidoBean
     */
    public EditarPedidoBean() {
        filtradoSQLGenerator=new FiltradoProductosSQLGenerator();
        filtradoDataModel=new FiltradoDataModel();
    }
    
    public void editar(){
        pedidoFacade.edit(pedido);
        eventoPedidoEditado.fire(pedido);
    }
    
    public void filtrar(){
        filtradoSQLGenerator.setDataModel(filtradoDataModel);
        String sql=filtradoSQLGenerator.generateSQL();
        getTablaPedidoDataModel().setSql(sql);
        lineasPedido=new HashMap<Integer, LineaPedido>();
        idsEnEspera=new HashMap<Integer,Integer>();
    }
    
    public void onNuevoPedido(@Observes @EventoEntidadCreada Pedido p){
        this.pedido=p;
        this.tablaPedidoDataModel.setPedido(p);
    }
    
    public void onEditarPedido(@Observes @EventoEntidadElegida Pedido p){
        this.pedido=p;
        this.tablaPedidoDataModel.setPedido(p);
    }
    
    public LineaPedido recuperarLineaPedidoDeProductoTallaVacia(Producto p, Talla t){
        LineaPedido lp=null;
        if(p!=null && t!=null){
            ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(), t.getIdTalla());
            if(pt!=null){
                if(!lineasPedido.containsKey(pt.getIdProductoTalla())){
                    LineaPedido linea=new LineaPedido();
                    linea.setCantidad(0);
                    linea.setPedido(pedido);
                    linea.setProductoTalla(pt);
                    lineasPedido.put(pt.getIdProductoTalla(), linea);
                }
                lp=lineasPedido.get(pt.getIdProductoTalla());
            }
        }
        return lp;
    }
    
    
    public void verCosas(){
        List<C> csDePedido=tablaPedidoDataModel.getCDePedido();
        for (C c : csDePedido) {
            List<SerieTallaje> series=tablaPedidoDataModel.getSeriesTallajeDePedidoYC(c);
            for (SerieTallaje serieTallaje : series) {
                List<Producto> productos=tablaPedidoDataModel.getTodosProductosDePedidoSerieTallajeYC(c, serieTallaje);
                for (Producto producto : productos) {
                    List<TallaSerieTallaje> tallasSer=serieTallaje.getTallaSerieTallajeList();
                    for (TallaSerieTallaje tallaSerieTallaje : tallasSer) {
                    }
                }
            }
        }
    }
    
    public LineaPedido recuperarLineaPedidoDeProductoTalla(Producto p, Talla t){
        LineaPedido linea=null;
        if(p!=null && t!=null){
            Boolean encontrado=false;
            for(LineaPedido lp: pedido.getLineaPedidoList()){
                if(lp.getProductoTalla().getProducto().getIdProducto()==p.getIdProducto() && lp.getProductoTalla().getTalla().getIdTalla()==t.getIdTalla()){
                    linea=lp;
                    encontrado=true;
                    break;
                }
            }
            if(!encontrado){
                if(p!=null && t!=null){
                    ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(), t.getIdTalla());
                    //ProductoTalla pt=productoTallaFacade.getProductoTallaDeProductoYTalla(p, t);
                    if(pt!=null){
                        linea=new LineaPedido();
                        linea.setCantidad(0);
                        linea.setPedido(pedido);
                        linea.setProductoTalla(pt);
                        pedido.getLineaPedidoList().add(linea);
                    }
                }
            }
        }
        return linea;
    }
    
    public void guardarProductos(){
        List<LineaPedido> lineasGuardar=new ArrayList<LineaPedido>();
        for(Iterator<LineaPedido> iter=pedido.getLineaPedidoList().iterator();iter.hasNext();){
            LineaPedido lp=iter.next();
            if(lp.getIdLineaPedido()!=null){
                if(lp.getCantidad()!=0){
                    lineaPedidoFacade.edit(lp);
                }
                else{
                    lineaPedidoFacade.remove(lp);
                    iter.remove();
                }
            }
            else if(lp.getCantidad()!=0){
                    lineaPedidoFacade.create(lp);
                    lineasGuardar.add(lp);
                    
            }
            else{
                iter.remove();
            }
        }
        pedido.getLineaPedidoList().addAll(lineasGuardar);
        //eventoEditarPedido.fire(0);
    }
    
    public void addProductos(){
        for(LineaPedido lp: lineasPedido.values()){
            if(lp.getCantidad()!=0){
                lineaPedidoFacade.create(lp);
                pedido.getLineaPedidoList().add(lp);
            }
        }
        lineasPedido=null;
    }
    
    public void editarProductoGuardado(Producto p, Talla t){
            LineaPedido lp=recuperarLineaPedidoDeProductoTalla(p, t);
            if(lp.getIdLineaPedido()!=null){
                if(lp.getCantidad()!=0){
                    lineaPedidoFacade.edit(lp);
                }
                else{
                    lineaPedidoFacade.remove(lp);
                }
            }
            else{
                if(lp.getCantidad()!=0){
                    lineaPedidoFacade.create(lp);
                }
            }
    }
    
    /*public void editarNuevoProducto(Producto p, Talla t){
        if(p!=null && t!=null){
            System.err.println("entra");
            ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(), t.getIdTalla());
            if(idsEnEspera.containsKey(pt.getIdProductoTalla())){
                Integer value=idsEnEspera.get(pt.getIdProductoTalla());
                value++;
                idsEnEspera.put(pt.getIdProductoTalla(), value);
            }
            else{
                idsEnEspera.put(pt.getIdProductoTalla(), 1);
                LineaPedido lp=recuperarLineaPedidoDeProductoTallaVacia(p, t);
                if(lp.getIdLineaPedido()!=null){
                    if(lp.getCantidad()!=0){
                        lineaPedidoFacade.edit(lp);
                    }
                    else{
                        lineaPedidoFacade.remove(lp);
                    }
                }
                else{
                    if(lp.getCantidad()!=0){
                        lineaPedidoFacade.create(lp);
                        //Poner en cuarentena. Si edita un valor antes de darle a terminar esto podría estar mal. PRUEBAS.
                        pedido.getLineaPedidoList().add(lp);
                    }
                }
                if(idsEnEspera.get(pt.getIdProductoTalla())>1){
                    System.err.println("Debe hacerlo de nuevo");
                    idsEnEspera.remove(pt.getIdProductoTalla());
                    editarNuevoProducto(p, t);
                }
                else{
                    idsEnEspera.remove(pt.getIdProductoTalla());
                }
            }
        }
    }
    */
    public void cerrarTablaAddProductos(){
        lineasPedido=null;
    }
    
    /**
     * @return the pedido
     */
    public Pedido getPedido() {
        return pedido;
    }

    /**
     * @param pedido the pedido to set
     */
    public void setPedido(Pedido pedido) {
        this.pedido = pedido;
    }
    
    /**
     * @return the tablaPedidoDataModel
     */
    public TablaPedidoDataModel getTablaPedidoDataModel() {
        return tablaPedidoDataModel;
    }

    /**
     * @param tablaPedidoDataModel the tablaPedidoDataModel to set
     */
    public void setTablaPedidoDataModel(TablaPedidoDataModel tablaPedidoDataModel) {
        this.tablaPedidoDataModel = tablaPedidoDataModel;
    }
    
      /**
     * @return the filtradoDataModel
     */
    public FiltradoDataModel getFiltradoDataModel() {
        return filtradoDataModel;
    }

    /**
     * @param filtradoDataModel the filtradoDataModel to set
     */
    public void setFiltradoDataModel(FiltradoDataModel filtradoDataModel) {
        this.filtradoDataModel = filtradoDataModel;
    }

    /**
     * @return the lineasPedido
     */
    public Map<Integer, LineaPedido> getLineasPedido() {
        return lineasPedido;
    }

    /**
     * @param lineasPedido the lineasPedido to set
     */
    public void setLineasPedido(Map<Integer, LineaPedido> lineasPedido) {
        this.lineasPedido = lineasPedido;
    }
}
